Bingo, Computer Graphics & Game Developer

冲量解决方案

1.在一个物理引擎当中一个物体对象通常有三个自由度 分别是xy轴上的自由平移和旋转

2.两物体碰撞 恢复系数取决于小的那个物体

3.冲量 = 动量改变量

Impulse=mass∗VelocityImpulse=mass*Velocity

Velocity=ImpulsemassVelocity=Impulsemass

V′=V+(j∗n)massV' = V + \frac{(j * n )}{mass}

此处的(j∗n)mass\frac{(j * n )}{mass} 表示速度改变量

4.这里的VABV_{AB}实质上是在应用了恢复系数之后的Vab′V_{ab}'

VAB′∗n=e∗(VB−VA)∗nV_{AB}' n = e (V_B - V_A)*n

原来式子中的负号是有误的

因此后面在使用这三个式子来推导最终结果的时候就可以理解了

VA′=VA+(j∗n)massAV'_A=V_A+\frac{(j*n)}{mass_A}

VB′=VB−(j∗n)massBV'_B=V_B-\frac{(j*n)}{mass_B}

5.正确的推导

(VB−VA−(j∗n)/massA−(j∗n)/massB)∗n=e∗(VB−VA)∗n(V_B-V_A-(j n) / mass_A-(j n) / mass_B)n= e (V_B-V_A) * n

(VB−VA)∗n−j∗((j∗n)/massA+(j∗n)/massB)∗n−e∗(VB−VA)∗n=0(V_B-V_A) n-j((j n) / mass_A+(j n)/ mass_B)n-e (V_B-V_A) * n= 0

(1+e)((VB−VA)∗n)+j∗((j∗n)massA+(j∗n)massB)∗n=0(1+e)((V_B-V_A) n)+j (\frac{(j n)}{mass_A} + \frac{(j n)}{mass_B}) * n=0

j=−(1+e)((VB−VA)∗n)(1/massA+1/massB)j=-\frac{(1+e)((V_B-V_A) * n)}{(1/mass_A+1/mass_B)}

原本的计算方式中虽然最终结果是正确的 但是推导过程中两次负号都出错 因此导致结果正确但是推导不正确的情况

6.预计算质量的倒数是非常有必要的

 A.inv_mass = 1 / A.mass

将 j 根据质量大小来分配给两个对象

mass_sum = A.mass + B.mass
float ratio = A.mass / mass_sum
A.velocity -= ratio * impulse

ratio = B.mass / mass_sum
B.velocity += ratio * impulse

PS:这个步骤 实质上就是ResolveCollision()这里也能看出来质量的倒数的重要性

7.位置修正的本质就是将两个互相碰撞的物体(在应用了冲量之后) 在其碰撞法线上移动一定距离(渗透距离的一定百分比 通常在20%~80%之间 作者推荐使用40%)